﻿using System;
using System.Linq;
using System.Data;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;
using EAF.Utility;
using EAF.DBC;
using EAF.DBC.LogHandle;
using EAF.Web;
using App.Utility;
using App.Utility.ComEntity;
using App.Utility.FileHandle;
using App.Model;
using App.Model.Main;
using App.DTO.Main;
using App.IServer.Main;
using App.Server.Main;

namespace App.Admin.Controllers
{
    /// <summary>
    /// 系统角色
    /// </summary>
    public class SysRoleController : ApiController
    {
        private readonly SysRoleService sysRoleService = null;
        private readonly SysModuleService sysModuleService = null;
        private readonly SysApiService sysApiService = null;
        private readonly SysPlatformService sysPlatformService = null;

        //使用依赖注入获取服务
        public SysRoleController(ISysRoleService sysRole, ISysModuleService sysModule, ISysApiService sysApi, ISysPlatformService sysPlatform)
        {
            sysRoleService = sysRole as SysRoleService;
            sysModuleService = sysModule as SysModuleService;
            sysApiService = sysApi as SysApiService;
            sysPlatformService = sysPlatform as SysPlatformService;
        }

        /// <summary>
        /// 获取平台所有模块权限
        /// </summary>
        ///  <param name="pId">平台id</param>
        /// <returns>操作结果</returns>
        [HttpGet]
        [AdminNoAction]
        public JsonR GetAllModuleApiTree(int pId)
        {
            var dbEntity = sysPlatformService.Detail(pId);
            if (dbEntity == null)
            {
                return RespCode.OP_未找到对象.JsonR("未找到此平台！");
            }
            else
            {
                var result = new List<AllModuleApiTreeResp>();
                AdminTokenOperation.HandleTreeAllModuleApi(result,
                    sysModuleService.GetCacheList().Where(a => a.PlatformId == pId).OrderBy(a => a.SortNo).ToList(),
                    sysApiService.GetCacheList().Where(a => a.PlatformId == pId).OrderBy(a => a.SortNo).ToList());
                return RespCode.OP_操作成功.JsonR(result);
            }
        }

        #region 增删改查列表分页等基础操作

        /// <summary>
        /// 分页列表
        /// </summary>
        /// <param name="model">查询参数</param>
        /// <returns>分页数据</returns>
        [HttpGet]
        public JsonR<JsonPage<SysRoleResp>> PageList([FromQuery] SysRolePageReq model)
        {
            var query = model.Query(sysRoleService.DBC);

            JsonPage<SysRoleResp> pageList = new JsonPage<SysRoleResp>();
            pageList.total = query.Count().ToInt();
            pageList.pageSize = model.pageSize;
            pageList.pageIndex = model.pageIndex;
            pageList.list = query.Page(model.pageIndex, model.pageSize).ToList(o => new SysRoleResp(o));

            var resp = RespCode.OP_操作成功.JsonRT(pageList);
            //resp.AddEnumKeyValueList(typeof(RespCode));
            return resp;
        }

        /// <summary>
        /// 导出excel
        /// </summary>
        /// <param name="model">查询参数</param>
        /// <param name="fields">需要导出的字段 如：id|</param>
        /// <param name="token">登录用户令牌</param>
        /// <param name="uId">登录用户Id</param>
        /// <param name="frontUrl">前端页面域名 末尾不要带/</param>
        /// <returns>excel文件流</returns>
        [HttpGet]
        [Produces("multipart/form-data")]
        [AdminNoLogin]
        [AdminNoAction]
        [AdminNoApiLog]
        public IActionResult ExportExcel([FromQuery] SysRolePageReq model, string fields = null, string token = "", int uId = 0, string frontUrl = "")
        {
            //验证权限 此接口可通过url直接访问
            var splitPath = Request.Path.ToString().Split('/', StringSplitOptions.RemoveEmptyEntries);
            var vr = AdminTokenOperation.VerifyToken(HttpContext, token, splitPath[1], splitPath[2], 0, uId);
            if (vr.code != RespCode.OP_操作成功.GetHashCode())
            {
                return Redirect(frontUrl + vr.body);
            }

            //查询数据
            var sql = model.Query(sysRoleService.DBC).ToSql();
            var dataTable = sysRoleService.DBC.SqlExecuteDataTable(sql);
            var tableInfo = sysRoleService.DBC.Orm.CodeFirst.GetTableByEntity(typeof(SysRole));

            //调整数据 移除无用列
            dataTable.Columns.Remove(tableInfo.ColumnsByCs[nameof(SysRole.Version)].Attribute.Name);
            dataTable.Columns.Remove(tableInfo.ColumnsByCs[nameof(SysRole.Deleted)].Attribute.Name);
            dataTable.Columns.Remove(tableInfo.ColumnsByCs[nameof(SysRole.DeleteTime)].Attribute.Name);

            //修改列名为字段注释
            dataTable.DataTableExportHandle<SysRole>(tableInfo, fields);

            RecordBehavior(new RLogBehavior
            {
                Table = nameof(SysRole),
                Method = EntityMethod.M_查看,
                Content = $"成功导出了ID为：{dataTable.GetColumnLong(tableInfo.ColumnsByCs[nameof(PrimaryKeyColumn<int>.Id)].Comment).ToJson()}的记录",
                Description = "导出excel"
            });

            //转换excel文件流 
            var fileName = (tableInfo.Comment.IsNull() ? nameof(SysRole) : tableInfo.Comment) + DateTime.Now.Format_yyyyMMddHHmmss(false) + ".xlsx";
            var byteFile = DoExcel.DataTableToExcelByte(dataTable, "sheet1", true, fileName);
            return File(byteFile, "application/octet-stream", fileName);
        }

        /// <summary>
        /// 导入excel
        /// </summary>
        /// <param name="file1">文件</param>
        /// <returns>操作结果</returns>
        [HttpPost]
        [Consumes("multipart/form-data")]
        [Transactional(typeof(AppMainContext), IsolationLevel.Serializable, "导入excel")]
        public JsonR ImportExcel(IFormFile file1 = null)
        {
            if (Request.Form.Files.Count == 0)
            {
                return RespCode.OP_参数异常.JsonR("请至少上传一个文件！");
            }

            var checkResult = file1.Admittance();
            if (checkResult.JsonResult.code == 0)
            {
                if (checkResult.FileType == "excel")
                {
                    //读取excel
                    var dataTable = DoExcel.ExcelStreamToDataTable(file1.OpenReadStream(), file1.FileName);
                    //列名转换为db实体类对应的字段名
                    var tableConfig = sysRoleService.DBC.Orm.CodeFirst.GetTableByEntity(typeof(SysRole));
                    dataTable.DataTableImportHandle<SysRole>(tableConfig);
                    //转换为db实体集合
                    var lstDbEntity = new List<SysRole>();
                    var dicError = new Dictionary<int, Dictionary<string, List<string>>>();
                    var dicProp = typeof(SysRole).GetProperties().ToDictionary(k => k.Name);
                    for (int i = 0; i < dataTable.Rows.Count; i++)
                    {
                        var row = dataTable.Rows[i];
                        var dbEntity = row.ToObject<SysRole>(dataTable.Columns, i, dicError, dicProp, tableConfig);
                        dbEntity.InitializeGeneralField(HttpContext);
                        lstDbEntity.Add(dbEntity);
                        //对每行数据业务验证 有问题请添加验证失败消息 dicError.AddImportVerifyError(i+2, "excel列名", "消息"); 不可移除集合数据 否则下方验证的行号可能无法对应

                    }

                    var insertIdentity = dataTable.Columns.Contains(nameof(SysRole.Id));
                    //通用检查实体类标记了[ImportRepeatVerify]的字段有没有重复值
                    var lstVerifyExcelRepeat = sysRoleService.DBC.VerifyImportRepeatColumn(lstDbEntity, dicError, tableConfig, insertIdentity, dicProp);
                    //通用检查实体类标记了[ImportRelationIdVerify(typeof(SysParam), nameof(SysParam.Name))]的字段外键关联记录是否存在
                    var dicVerifyExcelRelationId = sysRoleService.DBC.VerifyImportRelationIdColumn(lstDbEntity, dicError, tableConfig, dicProp);
                    //处理验证结果
                    var lstError = dicError.ToList();
                    var resp = new JsonImportError { errorTotal = lstError.Count, simpleMessage = lstError };
                    if (lstError.Count > 0)
                    {
                        return RespCode.OP_操作失败.JsonR(resp, $"数据验证失败有{resp.errorTotal}条不合法记录！");
                    }
                    //导入表 包含id则自动插入
                    int rowCount = sysRoleService.Add(lstDbEntity, insertIdentity);
                    return RespCode.OP_操作成功.JsonR($"成功导入{rowCount}条记录！");

                }
                else
                {
                    return RespCode.OP_操作失败.JsonR("上传的类型不支持，请上传excel文件！");
                }
            }
            else
            {
                return checkResult.JsonResult;
            }

        }

        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="entity">json对象</param>
        /// <returns>操作结果</returns>
        [HttpPost]
        [Transactional(typeof(AppMainContext), transDescription: "添加角色")]
        public JsonR Add([FromBody] SysRoleReq entity)
        {
            //var dbEntity = entity.ConvertDbEntity(new SysRole());
            //dbEntity.InitializeGeneralField(HttpContext);

            //var result = sysRoleService.Add(dbEntity);
            //if (result > 0)
            //{
            //    return RespCode.OP_操作成功.JsonR(new { insId = result });
            //}
            //else
            //{
            //    return RespCode.OP_操作失败.JsonR();
            //}

            var dbOldEntity = sysRoleService.Select.DisableGlobalFilter().Where(w => w.Name == entity.name).First();
            if (dbOldEntity != null)
            {
                return RespCode.OP_已有同名参数.JsonR($"名称{entity.name}已被使用");
            }

            List<int> lstModule = new List<int>();
            List<int> lstApi = new List<int>();
            //处理选择的树节点模块id和权限id 
            if (entity.selectedId != null && entity.selectedId.Count > 0)
            {
                //解析id
                for (int i = 0; i < entity.selectedId.Count; i++)
                {
                    if (entity.selectedId[i].StartsWith("a_"))
                    {
                        lstApi.Add(entity.selectedId[i].Replace("a_", "").ToInt());
                    }
                    else if (entity.selectedId[i].StartsWith("m_"))
                    {
                        lstModule.Add(entity.selectedId[i].Replace("m_", "").ToInt());
                    }
                }
                entity.apiIds = lstApi;
                entity.moduleIds = lstModule;
            }
            var dbEntity = entity.ConvertDbEntity(new SysRole());
            dbEntity.InitializeGeneralField();
            var result = sysRoleService.Add(dbEntity);
            if (result > 0)
            {
                dbEntity.Id = result;
                return RespCode.OP_操作成功.JsonR(new { insId = result });
            }
            else
            {
                return RespCode.OP_操作失败.JsonR();
            }
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="entity">json对象</param>
        /// <returns>操作结果</returns>
        [HttpPost]
        [Transactional(typeof(AppMainContext))]
        public JsonR Delete([FromBody] Json_ReqIds<int> entity)
        {
            if (entity == null || entity.ids == null)
            {
                return RespCode.OP_参数异常.JsonR();
            }

            int count = sysRoleService.Delete(entity.ids);
            return RespCode.OP_操作成功.JsonR(new { delCount = count });
        }

        /// <summary>
        /// 销毁
        /// </summary>
        /// <param name="entity">json对象</param>
        /// <returns>操作结果</returns>
        [HttpPost]
        [Transactional(typeof(AppMainContext))]
        public JsonR Destory([FromBody] Json_ReqIds<int> entity)
        {
            if (entity == null || entity.ids == null)
            {
                return RespCode.OP_参数异常.JsonR();
            }

            int count = sysRoleService.Delete(entity.ids, 1);

            return RespCode.OP_操作成功.JsonR(new { delCount = count });
        }

        /// <summary>
        /// 还原
        /// </summary>
        /// <param name="entity">json对象</param> 
        /// <returns>操作结果</returns>
        [HttpPost]
        [Transactional(typeof(AppMainContext))]
        public JsonR Restore([FromBody] Json_ReqIds<int> entity)
        {
            if (entity == null || entity.ids == null)
            {
                return RespCode.OP_参数异常.JsonR();
            }

            int count = sysRoleService.DBC.Update<SysRole>()
                .DisableGlobalFilter()
                .Set(f => f.Deleted, false)
                .Where(w => w.Deleted == true && entity.ids.Contains(w.Id)).ExecuteAffrows();

            if (count > 0)
            {
                sysRoleService.UpdateCache();

                RecordBehavior(new RLogBehavior
                {
                    Table = nameof(SysRole),
                    Method = EntityMethod.M_还原,
                    Content = $"还原了{count}条记录，ID为：{entity.ids.ToJson()}",
                    Description = "CRUD操作"
                });
            }

            return RespCode.OP_操作成功.JsonR(new { resCount = count });
        }

        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="entity">json对象</param>
        /// <returns>操作结果</returns>
        [HttpPost]
        [Transactional(typeof(AppMainContext), transDescription: "编辑角色权限")]
        public JsonR Modify([FromBody] SysRoleReq entity)
        {
            var dbOldEntity = sysRoleService.Detail(entity.id);
            var dbNewEntity = entity.ConvertDbEntity(dbOldEntity.AutoMapObjectTo(new SysRole()));
            if (dbNewEntity == null)
            {
                return RespCode.OP_未找到对象.JsonR();
            }
            else
            {
                List<int> lstModule = new List<int>();
                List<int> lstApi = new List<int>();
                List<int> lstAllModule = new List<int>();
                List<int> lstAllApi = new List<int>();
                List<int> lstDelModule = new List<int>();
                List<int> lstDelApi = new List<int>();
                //处理选择的树节点模块id和权限id 处理下发的指定平台所有模块和权限id 用于比对增加和删除id  allModuleApiTree为当前角色编辑前所有权限和模块id
                if (entity.selectedId != null && entity.currModuleApi != null && entity.platformId != 0)
                {
                    //解析id
                    for (int i = 0; i < entity.selectedId.Count; i++)
                    {
                        if (entity.selectedId[i].StartsWith("a_"))
                        {
                            lstApi.Add(entity.selectedId[i].Replace("a_", "").ToInt());
                        }
                        else if (entity.selectedId[i].StartsWith("m_"))
                        {
                            lstModule.Add(entity.selectedId[i].Replace("m_", "").ToInt());
                        }
                    }
                    for (int i = 0; i < entity.currModuleApi.Count; i++)
                    {
                        if (entity.currModuleApi[i].StartsWith("a_"))
                        {
                            var id = entity.currModuleApi[i].Replace("a_", "").ToInt();
                            if (sysApiService.GetCacheList().Where(a => a.Id == id && a.PlatformId == entity.platformId).FirstOrDefault() != null)
                            {
                                lstAllApi.Add(id);
                            }
                        }
                        else if (entity.currModuleApi[i].StartsWith("m_"))
                        {
                            var id = entity.currModuleApi[i].Replace("m_", "").ToInt();
                            if (sysModuleService.GetCacheList().Where(a => a.Id == id && a.PlatformId == entity.platformId).FirstOrDefault() != null)
                            {
                                lstAllModule.Add(id);
                            }
                        }

                    }
                    //检查删除
                    for (int i = 0; i < lstAllModule.Count; i++)
                    {
                        if (!lstModule.Contains(lstAllModule[i]))
                        {
                            lstDelModule.Add(lstAllModule[i]);
                        }
                    }
                    for (int i = 0; i < lstAllApi.Count; i++)
                    {
                        if (!lstApi.Contains(lstAllApi[i]))
                        {
                            lstDelApi.Add(lstAllApi[i]);
                        }
                    }
                    //开始删除
                    for (int i = 0; i < lstDelApi.Count; i++)
                    {
                        var a = lstDelApi[i];
                        if (dbNewEntity.ApiIds == null)
                        {
                            break;
                        }
                        if (dbNewEntity.ApiIds.Contains(a))
                        {
                            dbNewEntity.ApiIds.Remove(a);
                        }
                    }
                    for (int i = 0; i < lstDelModule.Count; i++)
                    {
                        var m = lstDelModule[i];
                        if (dbNewEntity.ModuleIds == null)
                        {
                            break;
                        }
                        if (dbNewEntity.ModuleIds.Contains(m))
                        {
                            dbNewEntity.ModuleIds.Remove(m);
                        }
                    }
                    //开始添加
                    for (int i = 0; i < lstApi.Count; i++)
                    {
                        var a = lstApi[i];
                        if (dbNewEntity.ApiIds == null)
                        {
                            dbNewEntity.ApiIds = new List<int>();
                            dbNewEntity.ApiIds.Add(a);
                            continue;
                        }
                        if (!dbNewEntity.ApiIds.Contains(a))
                        {
                            dbNewEntity.ApiIds.Add(a);
                        }
                    }
                    for (int i = 0; i < lstModule.Count; i++)
                    {
                        var m = lstModule[i];
                        if (dbNewEntity.ModuleIds == null)
                        {
                            dbNewEntity.ModuleIds = new List<int>();
                            dbNewEntity.ModuleIds.Add(m);
                            continue;
                        }
                        if (!dbNewEntity.ModuleIds.Contains(m))
                        {
                            dbNewEntity.ModuleIds.Add(m);
                        }
                    }
                }

                dbNewEntity.Name = entity.name;
                dbNewEntity.Description = entity.description;
                dbNewEntity.SortNo = entity.sortNo;
                dbNewEntity.Valid = entity.valid;

                var result = sysRoleService.Update(dbNewEntity, dbOldEntity);
                if (result > 0)
                {
                    return RespCode.OP_操作成功.JsonR();
                }
                else
                {
                    return RespCode.OP_操作失败.JsonR();
                }
            }
        }

        /// <summary>
        /// 详情
        /// </summary>
        ///  <param name="id">唯一标示</param>
        /// <returns>操作结果</returns>
        [HttpGet]
        public JsonR<SysRoleResp> Detail(int id)
        {
            var dbEntity = sysRoleService.Detail(id, true);
            if (dbEntity == null)
            {
                return RespCode.OP_未找到对象.JsonRT<SysRoleResp>();
            }

            var result = new SysRoleResp(dbEntity);

            var resp = RespCode.OP_操作成功.JsonRT(result);
            //添加用到键值对
            //resp.AddEnumKeyValueList(typeof(RespCode));
            return resp;
        }

        #endregion

    }
}



